﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace English_v2
{
    public partial class SentenceOrForm : Form
    {
        private System.IO.StreamReader sentencesFile= null;
        List<Label> labels = new List<Label>();
        Point shiftPoint;
        
        private bool isQuest = false;

        public bool IsQuest
        {
            get
            {
                return isQuest;
            }
            set
            {
                this.isQuest = value;
            }
        }
        
        public SentenceOrForm()
        {
            InitializeComponent();
        }

        private void SentenceOrForm_Load(object sender, EventArgs e)
        {
            if (this.setSentencesFile() == 0)
            {
                this.play(sender, e);
            }
            else
            {
                this.quit(sender, e);
            }
        }

        private int setSentencesFile()
        {
            if (isQuest)
            {
                this.setIsQuest();

                return this.openStream("Files/sentences_questions.csv");
            }
            this.setIsNotQuest();
            return this.openStream("Files/sentences_positive.csv");
            
        }

        private int openStream(string path)
        {
            try
            {
                this.sentencesFile = new System.IO.StreamReader(@path);
                return 0;
            }
            catch (Exception e)
            {
                MessageBox.Show("Chyba pri nacitavani suboru s vetami do SentenceOrForm\n[" + e.Message + "]");
                return -1;
            }
        }

        private void setIsNotQuest()
        {
            this.fileStartNormalMenu.Enabled = false;
            this.fileStartQuestionsMenu.Enabled = true;
            this.normalChangeContext.Enabled = false;
            this.questionsChangeContext.Enabled = true;
            this.Text = "Sentence ordering- Sentences mode";
            this.changeModeTool.Text = "Switch mode to questions";
            this.changeModeTool.Image = Properties.Resources.queston_icon;
        }

        private void setIsQuest()
        {
            this.fileStartNormalMenu.Enabled = true;
            this.fileStartQuestionsMenu.Enabled = false;
            this.normalChangeContext.Enabled = true;
            this.questionsChangeContext.Enabled = false;
            this.Text = "Sentence ordering- Questions mode";
            this.changeModeTool.Text = "Switch mode to sentences";
            this.changeModeTool.Image = Properties.Resources.dot_icon;
        }

        private void play(object sender, EventArgs e)
        {
            this.isNotCorrect();

            this.disposeOldLabels();
            this.generateLabels();

        }

        private void disposeOldLabels()
        {
            foreach (Label oldLabel in this.labels)
            {
                oldLabel.Dispose();
            }
            this.labels.Clear();
        }

        private void generateLabels()
        {
            string line = null;
            try
            {
                line = this.sentencesFile.ReadLine();
            } catch(Exception e)
            {
                MessageBox.Show("Chyba pri citani suboru pre SentenceOrForm\n[" + e.Message + "]");
                this.quit(null, null);
            }
            string[] words = line.Split(';');

            for (int i = 0; i < words.Length; i++)
            {
                labels.Add(new Label() );
                labels[i].Text = words[i];
            }
            
            this.setLabels();
        }

        private void setLabels()
        {
            Random randomGen = new Random();
            foreach (var label in labels)
            {
                label.Parent = this.notOrderedPanel;
                label.Top = randomGen.Next(65, this.notOrderedPanel.Height - 30);
                label.Left = randomGen.Next(100, this.notOrderedPanel.Width - 100);
                label.MouseDown += new MouseEventHandler(this.mouseDown);
                label.AutoSize = true;
                label.Font = new Font("Comic Sans MS", 15, FontStyle.Italic);
                label.Show();
            }
        }

        private void restart(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.No;
            if (isQuest)
            {
                this.DialogResult = DialogResult.Yes;
            }
            this.Close();
        }

        private void quit(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Abort;
            this.Close();
        }

        private void startNormal(object sender, EventArgs e)
        {
            if (this.isQuest)
            {
                this.DialogResult = DialogResult.No;
                this.Close();
            }
        }

        private void startQuestions(object sender, EventArgs e)
        {
            if (!this.isQuest)
            {
                this.DialogResult = DialogResult.Yes;
                this.Close();
            }
        }

        private void restartChangeMode(object sender, EventArgs r)
        {
            this.DialogResult = DialogResult.No;
            if (!isQuest)
            {
                this.DialogResult = DialogResult.Yes;
            }
            this.Close();
        }

        private void startTutorials(object sender, EventArgs e)
        {
            TutorialForm tutorial = new TutorialForm() { Page = 2 };
            tutorial.ShowDialog();
        }

        private void reset(object sender, EventArgs e)
        {
            List<Label> toReset = new List<Label>();
            int p = 1;
            addLabelsFromOrdered(ref toReset);
            addLabelsFromNotOrdered(ref toReset);
            foreach (var text in toReset)
            {
                p++;
                text.Parent = this.notOrderedPanel;
                text.Left = 0 + (p * 50);
                text.Top = this.notOrderedPanel.Height / 2 + ((p % 2) * 50);
            }
        }

        private void addLabelsFromOrdered(ref List<Label> toReset)
        {
            Random generator = new Random();
            foreach (Component control in this.orderedPanel.Controls)
            {
                if (control is Label)
                {
                    if (generator.Next() % 2 == 0)
                    {
                        toReset.Add((Label)control);
                    }
                    else
                    {
                        toReset.Insert(0, (Label)control);
                    }
                }
            }
        }

        private void addLabelsFromNotOrdered(ref List<Label> toReset)
        {
            Random generator = new Random();
            foreach (Component control in this.notOrderedPanel.Controls)
            {
                if (control is Label)
                {
                    if (generator.Next() % 2 == 0)
                    {
                        toReset.Add((Label)control);
                    }
                    else
                    {
                        toReset.Insert(0, (Label)control);
                    }
                }
            }
        }

        // Obsluha drag udalosti a kontrola po drope

        void mouseDown(object sender, MouseEventArgs e)
        {
            Label text = (Label)sender;
            this.shiftPoint.X = e.X;
            this.shiftPoint.Y = e.Y;
            text.DoDragDrop(text, DragDropEffects.Move);
        }

        void panel_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
            Label text = (Label)e.Data.GetData(typeof(Label));
            Panel actualPanel = (Panel)sender;
            text.Parent = actualPanel;
            Point transformPoint = actualPanel.PointToClient(new Point(e.X, e.Y));
            text.Left = transformPoint.X - this.shiftPoint.X ;
            text.Top = transformPoint.Y - this.shiftPoint.Y;
        }

        void panel_DragDrop(object sender, DragEventArgs e)
        {
            if (checkCorrect())
            {
                isCorrect();
            }
            else
            {
                isNotCorrect();
            }
        }

        private bool checkCorrect()
        {
            if (this.orderedPanel.Controls.Count == this.labels.Count)
            {
                string[] words = this.getWordsFromPanel();
                for (int i = 0; i < this.labels.Count; i++)
                {
                    if (words[i] != this.labels[i].Text)
                    {
                        return false;
                    }
                }
                return true;
            }
            return false;
        }

        private string[] getWordsFromPanel()
        {
            List<Label> sortedLabels;
            this.sortLabels(out sortedLabels);
            string[] words = new string[sortedLabels.Count()];
            for (int i = 0; i < sortedLabels.Count(); i++)
            {
                words[i] = sortedLabels[i].Text;
            }
            return words;
        }

        private List<Label> sortLabels(out List<Label> sortedLabels)
        {
            sortedLabels = new List<Label>();
            sortedLabels.Add(this.labels[0]);
            for (int i = 1; i < this.labels.Count(); i++)
            {
                int sLength = sortedLabels.Count();
                if (this.labels[i].Location.X > sortedLabels[sLength - 1].Location.X)
                {
                    sortedLabels.Add(this.labels[i]);
                }
                else
                {
                    for (int j = 0; j < sLength; j++)
                    {
                        if (this.labels[i].Location.X <= sortedLabels[j].Location.X)
                        {
                            sortedLabels.Insert(j, this.labels[i]);
                            break;
                        }
                    }
                }
            }
            return sortedLabels;
        }

        private void isCorrect()
        {
            alignLabels();
            this.orderedPanel.BackColor = Color.PaleGreen;
            this.nextTool.Enabled = true;
            this.fileNextMenu.Enabled = true;
            this.nextContext.Enabled = true;

            if (this.sentencesFile.EndOfStream)
            {
                sentencesFile.Close();
                showEndDialog();
            }
        }

        private void alignLabels()
        {
            foreach (Component comp in this.orderedPanel.Controls)
            {
                if (comp is Label)
                {
                    ((Label)comp).Top = this.orderedPanel.Height / 2;
                }
            }
        } 

        private void showEndDialog()
        {
            EndDialogForm edf = new EndDialogForm() { MiniAppMode = "sentenceForm" };
            DialogResult result = edf.ShowDialog();
            switch (result)
            {
                case DialogResult.Abort:
                    this.quit(null, null);
                    break;
                case DialogResult.Retry:
                    this.restart(null, null);
                    break;
                case DialogResult.Yes:
                    this.restartChangeMode(null, null);
                    break;
            }
        }

        private void isNotCorrect()
        {
            this.orderedPanel.BackColor = Color.IndianRed;
            this.nextTool.Enabled = false;
            this.fileNextMenu.Enabled = false;
            this.nextContext.Enabled = false;
        }

    }
}
